package com.leqicheng.tenon.util;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

import com.leqicheng.tenon.R;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.content.res.Configuration;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnTouchListener;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.Animation.AnimationListener;
import android.view.animation.TranslateAnimation;
import android.widget.FrameLayout;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.PopupWindow;
import android.widget.PopupWindow.OnDismissListener;
import android.widget.RelativeLayout;

public class MenuButton extends FrameLayout implements OnTouchListener,
        OnDismissListener, OnClickListener {

    public interface OnChooseListener {
        public void chooseBack(int index);
    }

    private final Context mContext;
    private int screenWidth;
    private int screenHeight;
    private int lastX;
    private int lastY;
    private int newX;
    private int newY;

    private View viewMenu;

    private PopupWindow pwMyPopWindow;

    private int mMoveStep;

    private boolean mNotClick;

    private LinearLayout LinearMenu;

    private LinearLayout allMenu;
    private final OnChooseListener mOnChooseListener;
    private LinearLayout mFirstMenu;
    private LinearLayout mSecondMenu;
    private LinearLayout mThirdMenu;
    private ImageButton menuButton;
    private FrameLayout menuBackground;
    private int menuButtonLastLeft;
    private int menuButtonLastRight;
    private int menuButtonLastTop;
    private int menuButtonLastBottom;
    private LinearLayout menuLayout;
    private boolean menuButtonMovable;
    private LinearLayout mForthMenu;
    private LinearLayout mFifthMenu;

    public MenuButton(Context context, OnChooseListener listener) {
        super(context);
        this.mContext = context;
        this.mOnChooseListener = listener;
        View menu = LayoutInflater.from(mContext).inflate(
                R.layout.tenon_menu_layout, null, true);
        this.addView(menu);
        menuButton = new ImageButton(mContext);
        menuButton.setPadding(5, 5, 5, 5);
        menuButton.setBackgroundResource(R.drawable.tenon_menu_icon);
        // LayoutParams mParams = new LayoutParams(100, 100);
        menuButton.setLayoutParams(new FrameLayout.LayoutParams(
                ViewGroup.LayoutParams.WRAP_CONTENT,
                ViewGroup.LayoutParams.WRAP_CONTENT));
        this.addView(menuButton);
        menuBackground = (FrameLayout) this
                .findViewById(R.id.tenon_menu_layout_id);
        menuBackground.setVisibility(View.INVISIBLE);
        menuBackground.setOnClickListener(this);

        menuLayout = (LinearLayout) this.findViewById(R.id.tenon_menu);
        this.mFirstMenu = (LinearLayout) this.menuLayout
                .findViewById(R.id.tenon_menu_first);
        this.mSecondMenu = (LinearLayout) this.menuLayout
                .findViewById(R.id.tenon_menu_second);
        this.mThirdMenu = (LinearLayout) this.menuLayout
                .findViewById(R.id.tenon_menu_third);
        this.mForthMenu = (LinearLayout) this.menuLayout
                .findViewById(R.id.tenon_menu_forth);
        mFifthMenu = (LinearLayout) this.menuLayout
                .findViewById(R.id.tenon_menu_fifth);
        this.mFirstMenu.setOnClickListener(this);
        this.mSecondMenu.setOnClickListener(this);
        this.mThirdMenu.setOnClickListener(this);
        this.mForthMenu.setOnClickListener(this);
        this.mFifthMenu.setOnClickListener(this);

        menuButtonMovable = true;

        initOrientation();
        this.setLayoutParams(new FrameLayout.LayoutParams(
                ViewGroup.LayoutParams.MATCH_PARENT,
                ViewGroup.LayoutParams.MATCH_PARENT));

        menuButton.setOnTouchListener(this);
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        ((Activity) mContext)
                .getWindow()
                .getDecorView()
                .setSystemUiVisibility(
                        View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                                | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                                | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                                | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
                                | View.SYSTEM_UI_FLAG_FULLSCREEN
                                | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
        super.onSizeChanged(w, h, oldw, oldh);
    }

    public void initOrientation() {
        DisplayMetrics dm = this.getResources().getDisplayMetrics();
        // if (mContext.getResources().getConfiguration().orientation ==
        // Configuration.ORIENTATION_PORTRAIT) {
        this.screenWidth = dm.widthPixels;
        this.screenHeight = dm.heightPixels;
        // } else {
        // this.screenWidth = dm.heightPixels;
        // this.screenHeight = dm.widthPixels;
        // }
    }

    @Override
    public boolean onTouch(final View v, MotionEvent event) {
        menuButton.setBackgroundResource(R.drawable.tenon_menu_icon);
        int ea = event.getAction();
        Log.i("TAG", "Touch:" + ea);
        this.mNotClick = false;

        int dl = v.getLeft();
        int db = v.getBottom();
        int dr = v.getRight();
        int dt = v.getTop();
        int llength = dl;
        int rlength = this.screenWidth - dr;
        int tlength = dt;
        int blength = this.screenHeight - db;
        String where = this.getWitchEdgeIsShortest(llength, rlength, tlength,
                blength);
        switch (ea) {
        case MotionEvent.ACTION_DOWN:
            Log.i("Tenon", "down");
            switch (where) {
            case "left":
                dl = 0;
                dr = 0 + v.getWidth();
                break;
            case "right":
                dl = this.screenWidth - v.getWidth();
                dr = this.screenWidth;
                break;
            case "top":
                dt = 0;
                db = 0 + v.getHeight();
                break;
            case "bottom":
                dt = this.screenHeight - v.getHeight();
                db = this.screenHeight;
                break;
            default:
                break;
            }
            v.layout(dl, dt, dr, db);
            v.postInvalidate();
            this.lastX = (int) event.getRawX();// 获取触摸事件触摸位置的原始X坐标
            this.lastY = (int) event.getRawY();
            break;

        case MotionEvent.ACTION_MOVE:
            if (menuButtonMovable) {
                this.mMoveStep++;
                Log.i("Tenon", "move       " + this.mMoveStep);
                int dx = (int) event.getRawX() - this.lastX;
                int dy = (int) event.getRawY() - this.lastY;

                int l = v.getLeft() + dx;
                int b = v.getBottom() + dy;
                int r = v.getRight() + dx;
                int t = v.getTop() + dy;
                // 下面判断移动是否超出屏幕 如果只是想与边框贴合就使用底下这个代码
                if (l < 0) {
                    l = 0;
                    r = l + v.getWidth();
                }

                if (t < 10) {
                    t = 10;
                    b = t + v.getHeight();
                }

                if (r > this.screenWidth) {
                    r = this.screenWidth;
                    l = r - v.getWidth();
                }

                if (b > this.screenHeight - 10) {
                    b = this.screenHeight - 10;
                    t = b - v.getHeight();
                }
                v.layout(l, t, r, b);

                this.lastX = (int) event.getRawX();
                this.lastY = (int) event.getRawY();
                v.postInvalidate();
            }
            break;
        case MotionEvent.ACTION_UP:
            if (this.mMoveStep > 5 || menuBackground.getVisibility() == VISIBLE) {
                menuButtonMovable = true;
                menuBackground.setVisibility(INVISIBLE);

                this.mMoveStep = 0;
                Log.i("Tenon", "up");
                this.newX = 0;
                this.newY = 0;
                switch (where) {
                case "left":
                    this.newX = -(llength + v.getWidth() / 2);
                    this.newY = 0;
                    break;
                case "right":
                    this.newX = rlength + v.getWidth() / 2;
                    this.newY = 0;
                    break;
                default:
                    break;
                }
                this.MoveToEdge();
                break;
            } else {
                menuButtonMovable = false;
                menuBackground.setVisibility(menuBackground.VISIBLE);
                switch (where) {
                case "left":
                    menuLayout.layout(
                            menuButton.getRight() - 50,
                            menuButton.getTop()
                                    - (menuLayout.getHeight() - menuButton
                                            .getHeight()) / 2,
                            menuButton.getRight() - 50 + menuLayout.getWidth(),
                            menuButton.getBottom()
                                    + (menuLayout.getHeight() - menuButton
                                            .getHeight()) / 2);
                    break;
                case "right":
                    menuLayout.layout(
                            menuButton.getLeft() + 50 - menuLayout.getWidth(),
                            menuButton.getTop()
                                    - (menuLayout.getHeight() - menuButton
                                            .getHeight()) / 2,
                            menuButton.getLeft() + 50,
                            menuButton.getBottom()
                                    + (menuLayout.getHeight() - menuButton
                                            .getHeight()) / 2);
                    break;
                default:
                    break;
                }
            }
            break;
        }
        return true;
    }

    @Override
    public void onDismiss() {

        int dl = menuButton.getLeft();
        int db = menuButton.getBottom();
        int dr = menuButton.getRight();
        int dt = menuButton.getTop();
        int llength = dl;
        int rlength = this.screenWidth - dr;
        int tlength = dt;
        int blength = this.screenHeight - db;
        String where = this.getWitchEdgeIsShortest(llength, rlength, tlength,
                blength);
        Log.i("Tenon", "up");
        this.newX = 0;
        this.newY = 0;
        switch (where) {
        case "left":
            this.newX = -(llength + menuButton.getWidth() / 2);
            this.newY = 0;
            break;
        case "right":
            this.newX = rlength + menuButton.getWidth() / 2;
            this.newY = 0;
            break;
        case "top":
            this.newX = 0;
            this.newY = -(tlength + menuButton.getHeight() / 2);
            break;
        case "bottom":
            this.newX = 0;
            this.newY = blength + menuButton.getHeight() / 2;
            break;
        default:
            break;
        }
        this.MoveToEdge();
    }

    private String getWitchEdgeIsShortest(int llength, int rlength,
            int tlength, int blength) {
        ArrayList alist = new ArrayList();
        Map<Integer, String> map = new HashMap<Integer, String>();
        map.put(llength, "left");
        map.put(rlength, "right");
        // 引起重绘，功能关闭
        // map.put(tlength, "top");
        // map.put(blength, "bottom");
        // alist.add(tlength);
        // alist.add(blength);
        alist.add(llength);
        alist.add(rlength);
        int key = Collections.min(alist);
        return map.get(key);
    }

    @SuppressLint("NewApi")
    private void MoveToEdge() {
        Animation myAnimation_Translate = new TranslateAnimation(0, this.newX,
                0, this.newY);
        myAnimation_Translate.setDuration(200);
        menuButton.startAnimation(myAnimation_Translate);
        myAnimation_Translate.setAnimationListener(new AnimationListener() {

            @Override
            public void onAnimationStart(Animation animation) {
                // TODO Auto-generated method stub

            }

            @Override
            public void onAnimationRepeat(Animation animation) {
                // TODO Auto-generated method stub

            }

            @Override
            public void onAnimationEnd(Animation animation) {
                menuButton.layout(menuButton.getLeft() + MenuButton.this.newX,
                        menuButton.getTop() + MenuButton.this.newY,
                        menuButton.getRight() + MenuButton.this.newX,
                        menuButton.getBottom() + MenuButton.this.newY);
                TranslateAnimation anim = new TranslateAnimation(0, 0, 0, 0);
                menuButton.setAnimation(anim);
            }
        });
        menuButton.setBackgroundResource(R.drawable.tenon_menu_icon_half_alpha);
    }

    @Override
    public void onClick(View v) {
        if (v.getId() == R.id.tenon_menu_first) {
            this.mOnChooseListener.chooseBack(1);
            this.dismissPopWindow();
        } else if (v.getId() == R.id.tenon_menu_second) {
            this.mOnChooseListener.chooseBack(2);
            this.dismissPopWindow();
        } else if (v.getId() == R.id.tenon_menu_third) {
            this.mOnChooseListener.chooseBack(3);
            this.dismissPopWindow();
        } else if (v.getId() == R.id.tenon_menu_forth) {
            this.mOnChooseListener.chooseBack(4);
            this.dismissPopWindow();
        } else if (v.getId() == R.id.tenon_menu_fifth) {
            this.mOnChooseListener.chooseBack(5);
            this.dismissPopWindow();
        } else if (v.getId() == R.id.tenon_menu_layout_id) {
            menuButtonMovable = true;
            this.dismissPopWindow();
            onDismiss();
        }
    }

    private void dismissPopWindow() {
        menuBackground.setVisibility(menuBackground.INVISIBLE);
    }

    public void setWindowParams(int screenWidth2, int screenHeight2) {
        // TODO Auto-generated method stub
        screenHeight = screenHeight2;
        screenWidth = screenWidth2;
    }
}
